package builtin

import (
	"bufio"
	"context"
	"fmt"
	"os"
	"strings"
	"sync"
	"time"

	"pwsh-go/internal/powershell"
)

// EnhancedAgent represents a Cursor-style AI agent with tool calling capabilities
type EnhancedAgent struct {
	mu               sync.Mutex
	backend          powershell.Backend
	reader           *bufio.Reader
	toolRegistry     *ToolRegistry
	messages         []Message
	contextMessages  []Message
	workingDirectory string
	taskHistory      []Task
	currentTask      *Task
	ctx              context.Context
	cancel           context.CancelFunc
}

// Task represents a high-level task being executed by the agent
type Task struct {
	ID          string    `json:"id"`
	Description string    `json:"description"`
	Status      string    `json:"status"` // pending, in_progress, completed, failed
	Steps       []Step    `json:"steps"`
	StartTime   time.Time `json:"start_time"`
	EndTime     time.Time `json:"end_time,omitempty"`
	Result      string    `json:"result,omitempty"`
	Error       string    `json:"error,omitempty"`
}

// Step represents a single step in a task
type Step struct {
	ID          string    `json:"id"`
	Description string    `json:"description"`
	Action      string    `json:"action"` // tool_call, command, analysis
	Details     string    `json:"details"`
	Status      string    `json:"status"` // pending, executing, completed, failed
	StartTime   time.Time `json:"start_time"`
	EndTime     time.Time `json:"end_time,omitempty"`
	Result      string    `json:"result,omitempty"`
	Error       string    `json:"error,omitempty"`
}

// NewEnhancedAgent creates a new enhanced agent instance
func NewEnhancedAgent(backend powershell.Backend) *EnhancedAgent {
	return &EnhancedAgent{
		backend:      backend,
		reader:       bufio.NewReader(os.Stdin),
		toolRegistry: NewToolRegistry(backend),
		messages:     make([]Message, 0),
		taskHistory:  make([]Task, 0),
	}
}

// Start begins the enhanced agent mode
func (ea *EnhancedAgent) Start() error {
	if activeClient == nil {
		return fmt.Errorf("❌ 请先连接 AI 服务 (使用 'ai openai' 或 'ai coze')")
	}

	// Initialize context
	ea.ctx, ea.cancel = context.WithCancel(context.Background())
	defer ea.cancel()

	// Get current working directory
	wd, err := os.Getwd()
	if err != nil {
		wd = "未知目录"
	}
	ea.workingDirectory = wd

	// Initialize context messages with enhanced system prompt
	ea.contextMessages = []Message{
		{
			Role:    "system",
			Content: ea.getEnhancedSystemPrompt(),
		},
		{
			Role:    "system",
			Content: fmt.Sprintf("Current working directory: %s", wd),
		},
	}

	// Add tool descriptions to context
	toolDescriptions := ea.getToolDescriptions()
	ea.contextMessages = append(ea.contextMessages, Message{
		Role:    "system",
		Content: fmt.Sprintf("Available tools: %s", toolDescriptions),
	})

	fmt.Println("🚀 Enhanced PowerShell Agent 模式已启动！")
	fmt.Println("💡 这是一个类似 Cursor 的智能代理，可以端到端完成复杂任务")
	fmt.Println("🔧 支持工具调用：文件操作、命令执行、目录浏览等")
	fmt.Println("📝 输入 'exit' 退出，输入 'help' 查看更多命令")
	fmt.Println("")

	return ea.runMainLoop()
}

// getEnhancedSystemPrompt returns the enhanced system prompt for Cursor-style agent
func (ea *EnhancedAgent) getEnhancedSystemPrompt() string {
	return `You are an Enhanced PowerShell Agent, similar to Cursor's AI assistant.

Your capabilities:
1. **End-to-End Task Completion**: Break down complex tasks into steps and execute them systematically
2. **Tool Calling**: Use available tools for file operations, command execution, and system interaction
3. **Context Awareness**: Maintain awareness of the current working directory, recent actions, and project state
4. **Intelligent Planning**: Analyze requirements and create execution plans before taking action
5. **Error Recovery**: Detect issues and attempt automatic recovery or suggest solutions

When a user provides a task:
1. First, analyze the task and break it down into logical steps
2. Use appropriate tools to gather information (read files, list directories, etc.)
3. Execute the necessary actions using tool calls or PowerShell commands
4. Provide clear feedback on progress and results
5. Handle errors gracefully and suggest alternatives

Tool Call Format:
To use a tool, respond with JSON in this format:
{"name": "tool_name", "arguments": {"arg1": "value1", "arg2": "value2"}}

For PowerShell commands, use the execute_command tool:
{"name": "execute_command", "arguments": {"command": "Get-ChildItem"}}

Always explain what you're doing and why. Keep the user informed of your progress.
If a task requires multiple steps, execute them one by one and report progress.

Available commands:
- help: Show available commands and tools
- tasks: Show current and recent tasks
- clear: Clear conversation history
- exit: Exit enhanced agent mode`
}

// getToolDescriptions returns descriptions of all available tools
func (ea *EnhancedAgent) getToolDescriptions() string {
	tools := ea.toolRegistry.ListTools()
	var descriptions []string
	for _, tool := range tools {
		descriptions = append(descriptions, fmt.Sprintf("%s: %s", tool.Name(), tool.Description()))
	}
	return strings.Join(descriptions, "; ")
}

// runMainLoop runs the main interaction loop
func (ea *EnhancedAgent) runMainLoop() error {
	for {
		select {
		case <-ea.ctx.Done():
			return nil
		default:
		}

		if err := ea.handleUserInput(); err != nil {
			if err.Error() == "exit" {
				return nil
			}
			return err
		}
	}
}

// handleUserInput processes user input and coordinates task execution
func (ea *EnhancedAgent) handleUserInput() error {
	fmt.Print("🤖 请描述您的任务: ")
	line, err := ea.reader.ReadString('\n')
	if err != nil {
		return fmt.Errorf("failed to read input: %w", err)
	}

	line = strings.TrimSpace(line)
	if line == "" {
		return nil
	}

	// Handle special commands
	switch strings.ToLower(line) {
	case "exit":
		fmt.Printf("\033[32m👋 退出 Enhanced Agent 模式\033[0m\n")
		return fmt.Errorf("exit")
	case "help":
		ea.showHelp()
		return nil
	case "tasks":
		ea.showTasks()
		return nil
	case "clear":
		ea.clearHistory()
		return nil
	}

	// Create a new task for this request
	task := &Task{
		ID:          fmt.Sprintf("task_%d", time.Now().Unix()),
		Description: line,
		Status:      "pending",
		Steps:       make([]Step, 0),
		StartTime:   time.Now(),
	}

	ea.mu.Lock()
	ea.currentTask = task
	ea.taskHistory = append(ea.taskHistory, *task)
	ea.mu.Unlock()

	fmt.Printf("\033[36m📋 开始执行任务: %s\033[0m\n", task.Description)
	fmt.Printf("\033[90m🆔 任务ID: %s\033[0m\n", task.ID)

	return ea.executeTask(task, line)
}

// executeTask executes a task using the AI agent
func (ea *EnhancedAgent) executeTask(task *Task, userInput string) error {
	task.Status = "in_progress"

	// Update working directory context
	wd, err := os.Getwd()
	if err == nil && wd != ea.workingDirectory {
		ea.workingDirectory = wd
		ea.updateContextMessage("system", fmt.Sprintf("Current working directory: %s", wd))
	}

	// Build message history
	fullMessages := append([]Message{}, ea.contextMessages...)
	fullMessages = append(fullMessages, ea.messages...)
	fullMessages = append(fullMessages, Message{
		Role:    "user",
		Content: userInput,
	})

	// Get AI response
	response, err := activeClient(fullMessages)
	if err != nil {
		fmt.Printf("\033[31m❌ AI 调用失败: %v\033[0m\n", err)
		task.Status = "failed"
		task.Error = err.Error()
		task.EndTime = time.Now()
		return nil
	}

	fmt.Printf("\033[32m🤖 AI 响应:\033[0m %s\n", response)

	// Parse and execute tool calls
	toolCalls, err := ParseToolCalls(response)
	if err != nil {
		fmt.Printf("\033[33m⚠️ 解析工具调用失败: %v\033[0m\n", err)
	}

	if len(toolCalls) > 0 {
		fmt.Printf("\033[36m🔧 执行 %d 个工具调用...\033[0m\n", len(toolCalls))
		for i, toolCall := range toolCalls {
			fmt.Printf("\033[90m  %d. %s\033[0m\n", i+1, toolCall.Name)
			result := ea.toolRegistry.ExecuteTool(toolCall.Name, toolCall.Arguments)
			
			if result.Success {
				fmt.Printf("\033[32m    ✅ 成功: %s\033[0m\n", result.Output)
			} else {
				fmt.Printf("\033[31m    ❌ 失败: %s\033[0m\n", result.Error)
			}

			// Add step to task
			step := Step{
				ID:          fmt.Sprintf("step_%d_%d", time.Now().Unix(), i),
				Description: fmt.Sprintf("Execute %s", toolCall.Name),
				Action:      "tool_call",
				Details:     fmt.Sprintf("%+v", toolCall.Arguments),
				Status:      "completed",
				StartTime:   time.Now(),
				EndTime:     time.Now(),
				Result:      result.Output,
			}
			if !result.Success {
				step.Status = "failed"
				step.Error = result.Error
			}
			task.Steps = append(task.Steps, step)
		}
	} else {
		// If no tool calls, check if it's a direct PowerShell command
		command := ea.extractPureCode(response)
		if command != "" {
			fmt.Printf("\033[36m⚡ 执行 PowerShell 命令: %s\033[0m\n", command)
			result := ea.toolRegistry.ExecuteTool("execute_command", map[string]interface{}{
				"command": command,
			})

			if result.Success {
				fmt.Printf("\033[32m✅ 命令执行成功:\033[0m\n%s\n", result.Output)
			} else {
				fmt.Printf("\033[31m❌ 命令执行失败: %s\033[0m\n", result.Error)
			}

			// Add step to task
			step := Step{
				ID:          fmt.Sprintf("step_%d", time.Now().Unix()),
				Description: "Execute PowerShell command",
				Action:      "command",
				Details:     command,
				Status:      "completed",
				StartTime:   time.Now(),
				EndTime:     time.Now(),
				Result:      result.Output,
			}
			if !result.Success {
				step.Status = "failed"
				step.Error = result.Error
			}
			task.Steps = append(task.Steps, step)
		}
	}

	// Update conversation history
	ea.messages = append(ea.messages, Message{
		Role:    "user",
		Content: userInput,
	})
	ea.messages = append(ea.messages, Message{
		Role:    "assistant",
		Content: response,
	})

	// Complete task
	task.Status = "completed"
	task.EndTime = time.Now()
	task.Result = "Task completed successfully"

	fmt.Printf("\033[32m🎉 任务完成! 耗时: %v\033[0m\n", task.EndTime.Sub(task.StartTime))

	return nil
}

// extractPureCode extracts pure PowerShell code from AI response (reuse from existing agent)
func (ea *EnhancedAgent) extractPureCode(response string) string {
	// This would reuse the existing extractPureCode logic
	// For now, simplified implementation
	lines := strings.Split(response, "\n")
	var codeLines []string

	for _, line := range lines {
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		}

		// Skip markdown code blocks
		if strings.HasPrefix(line, "```") {
			continue
		}

		// Skip explanatory text
		if strings.HasPrefix(line, "#") || 
		   strings.Contains(line, "这个命令") ||
		   strings.Contains(line, "这将") {
			continue
		}

		// Check if it looks like PowerShell code
		if strings.Contains(line, "Get-") ||
		   strings.Contains(line, "Set-") ||
		   strings.Contains(line, "New-") ||
		   strings.Contains(line, "Remove-") ||
		   strings.Contains(line, "$") {
			codeLines = append(codeLines, line)
		}
	}

	return strings.Join(codeLines, "\n")
}

// updateContextMessage updates or adds a context message
func (ea *EnhancedAgent) updateContextMessage(role, content string) {
	ea.mu.Lock()
	defer ea.mu.Unlock()

	// Find existing message with same role and update, or add new one
	for i, msg := range ea.contextMessages {
		if msg.Role == role && strings.Contains(msg.Content, "Current working directory") {
			ea.contextMessages[i].Content = content
			return
		}
	}

	// Add new context message
	ea.contextMessages = append(ea.contextMessages, Message{
		Role:    role,
		Content: content,
	})
}

// showHelp displays help information
func (ea *EnhancedAgent) showHelp() {
	fmt.Println("\033[36m🔧 Enhanced PowerShell Agent 帮助\033[0m")
	fmt.Println("")
	fmt.Println("可用命令:")
	fmt.Println("  help   - 显示此帮助信息")
	fmt.Println("  tasks  - 显示任务历史")
	fmt.Println("  clear  - 清除对话历史")
	fmt.Println("  exit   - 退出 Enhanced Agent 模式")
	fmt.Println("")
	fmt.Println("可用工具:")
	tools := ea.toolRegistry.ListTools()
	for _, tool := range tools {
		fmt.Printf("  %s - %s\n", tool.Name(), tool.Description())
	}
	fmt.Println("")
	fmt.Println("使用方法:")
	fmt.Println("  直接描述您想要完成的任务，Agent 会自动分解并执行")
	fmt.Println("  例如: '创建一个新的文件夹并在其中创建一个README文件'")
	fmt.Println("")
}

// showTasks displays task history
func (ea *EnhancedAgent) showTasks() {
	ea.mu.Lock()
	defer ea.mu.Unlock()

	fmt.Println("\033[36m📋 任务历史\033[0m")
	fmt.Println("")

	if len(ea.taskHistory) == 0 {
		fmt.Println("暂无任务历史")
		return
	}

	for i, task := range ea.taskHistory {
		statusColor := "\033[32m" // green for completed
		if task.Status == "failed" {
			statusColor = "\033[31m" // red for failed
		} else if task.Status == "in_progress" {
			statusColor = "\033[33m" // yellow for in progress
		}

		fmt.Printf("%d. %s%s\033[0m - %s\n", i+1, statusColor, task.Status, task.Description)
		fmt.Printf("   ID: %s\n", task.ID)
		fmt.Printf("   开始时间: %s\n", task.StartTime.Format("2006-01-02 15:04:05"))
		if !task.EndTime.IsZero() {
			fmt.Printf("   结束时间: %s\n", task.EndTime.Format("2006-01-02 15:04:05"))
			fmt.Printf("   耗时: %v\n", task.EndTime.Sub(task.StartTime))
		}
		if len(task.Steps) > 0 {
			fmt.Printf("   步骤数: %d\n", len(task.Steps))
		}
		if task.Error != "" {
			fmt.Printf("   错误: %s\n", task.Error)
		}
		fmt.Println()
	}
}

// clearHistory clears conversation history
func (ea *EnhancedAgent) clearHistory() {
	ea.mu.Lock()
	defer ea.mu.Unlock()

	ea.messages = make([]Message, 0)
	fmt.Println("\033[32m✅ 对话历史已清除\033[0m")
}